#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "misc-tr700-stm32.h"
#include "printl.h"
#include "stm32-spi.h"


#define C_SPEED (100000)
#define DEF_SPI "/dev/spidev2.0"


/**********************************************************
  构造函数
*/
static char *device_name = DEF_SPI;
static void __attribute__((constructor)) _load_env()
{
    char *env = NULL;
    env       = getenv("DEVICE_BACKBOARD_SPI");
    if (env) {
	device_name = env;
    }
}


int _msg_stm_open(int ret)
{
    switch (ret) {
    case -1:
	printf("bus error\n");
	return -1;
    case -2:
	printf("unknow device ID\n");
	return -1;
    }
    return 0;
}


int tr700_stm_open(struct dev_stm_info *dsi)
{
    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    int                   ret;

    // 这种封装每次都打开效率比较低下
    ret = stm_open(device_name, &dev, C_SPEED);
    if (ret) {
	return _msg_stm_open(ret);
    }
    stm_ls_wavelist(dev, NULL, 0);
    dsi->dev = dev;
    return 0;
}

int tr700_stm_close(struct dev_stm_info *dsi)
{
    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    stm_close(dev);
    return 0;
}

int tr700_ls_on(
	struct dev_stm_info *dsi,
	int                  nm,
	float                power_dBm,
	int                  mode)
{
    // printf("%s()\r\n", __FUNCTION__);
    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    int                   ret;

    printf("dev desc %s\r\n", dev->desc);

    int ch = stm_wave2ch(dev, nm);
    if (ch == 0) {
	printf("不存在波长%d\r\n", nm);
	return -1;
    }


    struct tr700_setls_tx val;
    val.ch   = ch;
    val.mode = mode;
    val.dbm  = power_dBm;
    printf("ch %d mode %d dbm %f\r\n",
           val.ch,
           val.mode,
           val.dbm);
    ret = stm_setls(dev, &val);
    // stm_close(dev);
    return ret;
}

int tr700_ls_off(
	struct dev_stm_info *dsi)
{
    // printf("%s()\r\n", __FUNCTION__);
    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    int                   ret;

    struct tr700_setls_tx val;

    val.ch   = LS_CH_OFF;
    val.mode = LS_MODE_CW;
    val.dbm  = -10;
    ret      = stm_setls(dev, &val);
    return ret;
}


int tr700_opm_read(
	struct dev_stm_info *dsi,
	int                  nm,
	float                ref_dBm,
	float               *power_mW,
	float               *power_dBm,
	float               *power_ref)
{
    // printf("%s()\r\n", __FUNCTION__);

    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    int                   ret;

    {
	struct tr700_setopm val;
	val.wave = (short)nm;
	stm_setopm(dev, &val);
    }


    {
	struct tr700_getopm val;
	ret = stm_getopm(dev, &val);
	if (power_dBm) {
	    *power_dBm = val.dbm;
	}
	if (power_ref) {
	    *power_ref = val.dbm - ref_dBm;
	}

	if (power_mW) {
	    *power_mW = pow(10, val.dbm / 10);
	}
    }
    return ret;
}


int tr700_opm_getref(
	struct dev_stm_info *dsi,
	int                  nm,
	float               *power_dBm)
{
    // printf("%s()\r\n", __FUNCTION__);

    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    int                   ret;

    {
	struct tr700_setopm val;
	val.wave = (short)nm;
	stm_setopm(dev, &val);
    }


    {
	struct tr700_getopm val;
	ret        = stm_getopm(dev, &val);
	*power_dBm = val.dbm;
    }
    return ret;
}


void tr700_ls_wavelist(struct dev_stm_info *dsi, int *otdrls)
{
    struct stm32_spi_dev *dev = (struct stm32_spi_dev *)dsi->dev;
    struct wave_list      list[3];

    printf(C_YELLOW "\r\n读取通道、波长信息，方法2：\r\n" C_NORMAL);
    stm_ls_wavelist(dev, list, 3);

    otdrls[0] = list[0].wave;
    otdrls[1] = list[1].wave;
    otdrls[2] = list[2].wave;
    otdrls[3] = 0;
}